#include "joystick.h"

vector<Joystick*> Joystick::sActives;

Joystick::Joystick(const string& name, ClassId* classId, int deviceIndex):
Instance(name, classId),
mSdlJoystick(SDL_JoystickOpen(deviceIndex))
{
    assert((unsigned int)deviceIndex < sActives.size());

    if (mSdlJoystick) {
        if(sActives[deviceIndex])
            delete sActives[deviceIndex];
        sActives[deviceIndex] = this;
    }
    else
        cerr << "Jostick::Joystick(name, deviceIndex, classId) : Could not open Joystick #" << deviceIndex << endl;
}

Joystick::~Joystick()
{
    if(mSdlJoystick) {
        int deviceIndex = SDL_JoystickIndex(mSdlJoystick);
        assert((unsigned int)deviceIndex < sActives.size());
        sActives[deviceIndex] = 0;
        SDL_JoystickClose(mSdlJoystick);
        mSdlJoystick = 0;
    }
}

Joystick* Joystick::getActive(unsigned int index)
{
    if(index < sActives.size())
        return sActives[index];
    return 0;
}

bool Joystick::detectActive()
{
    unsigned int i, numJoysticks;

    // Delete already active joysticks
    numJoysticks = sActives.size();
    for (i=0; i<numJoysticks; i++)
        delete sActives[i];

    // Detect & create active joysticks
    numJoysticks = SDL_NumJoysticks();
    sActives.resize(numJoysticks);
    for (i=0; i<numJoysticks; i++) {
        sActives[i] = 0;
        new Joystick(SDL_JoystickName(i), Joystick::sClassId, i);
        if (!sActives[i])
            return false;
    }
    return true;
}

void Joystick::handleAxisEvent(SDL_JoyAxisEvent* event, float dt)
{
    assert(event);
    Joystick* joystick = Joystick::getActive(event->which);
    if(joystick)
        joystick->onAxisMotion(event->axis, event->value, dt);
}

void Joystick::onAxisMotion(Uint8 axis, int x, float dt)
{
}

void Joystick::handleBallEvent(SDL_JoyBallEvent* event, float dt)
{
    assert(event);
    Joystick* joystick = Joystick::getActive(event->which);
    if(joystick)
        joystick->onBallMotion(event->ball, event->xrel, event->yrel, dt);
}

void Joystick::onBallMotion(Uint8 ball, int dx, int dy, float dt)
{
}

void Joystick::handleHatEvent(SDL_JoyHatEvent* event, float dt)
{
    assert(event);
    Joystick* joystick = Joystick::getActive(event->which);
    if(joystick)
        joystick->onHatMotion(event->hat, event->value, dt);
}

void Joystick::onHatMotion(Uint8 hat, Uint8 value, float dt)
{
}

void Joystick::handleButtonEvent(SDL_JoyButtonEvent* event, float dt)
{
    assert(event);
    Joystick* joystick = Joystick::getActive(event->which);
    if(joystick) {
        if (event->type == SDL_JOYBUTTONDOWN)
            joystick->onButtonDown(event->button, dt);
        else
            joystick->onButtonUp(event->button, dt);
    }

}

void Joystick::onButtonDown(Uint8 button, float dt)
{
}

void Joystick::onButtonUp(Uint8 button, float dt)
{
}

bool Joystick::load(DataStream* ds)
{
    INSTANCE_LOAD(ds);

    return true;
}

bool Joystick::save(DataStream* ds)
{
    INSTANCE_SAVE(ds);

    return true;
}
